define([this.path + './../4.x/plugins/esri/layers/CanvasLayer.js'], function (CanvasLayer) {
    var HeatMapLayer = CanvasLayer.createSubclass({
        constructor: function (o) {
            this.view = o.view;
            this.minnum = 1;
            this.maxnum = 1;
            this.visible = true;
            this.createCanvas();
            this.startMapEventListeners();
        },
        setData: function (mapView, mapUtils, layer) {
            var options = layer.layer || {};
            var data = options.data || [];
            this._options = options;
            this.config = {
                radius: 20,
                gradient: {
                    0.25: "rgb(0,0,255)",
                    0.55: "rgb(0,255,0)",
                    0.85: "rgb(255,255,0)",
                    1.0: "rgb(255,0,0)"
                },
                ...options.options
            };
            this._mapView = mapView;
            this._mapUtils = mapUtils;
            this.data = data;
            this.lngFieldName = options.lngFieldName || mapView.getLngFieldName();
            this.latFieldName = options.latFieldName || mapView.getLatFieldName();
            this.countFieldName = options.countFieldName || mapView.getCountFieldName();
            this.gradient = this.config.gradient;
            var points = [];
            data.map(function (item) {
                points.push({...item, point: mapUtils.createPoint(mapView, item, options)});
            });
            this.addPoint(points);


            if (options.options.isShowLegend) {
                this.getLegend(mapView,this.config);
            }
            if (typeof options.callback == 'function') {
                options.callback(layer);
            }
            ;
        },
        /*转换数据*/
        convertHeatmapData: function (data) {
            var heatPluginData = [];
            for (let i = 0; i < data.length; i++) {
                let screenpoint = this._mapUtils.mapPointToScreen(this._mapView,data[i].point);
                var count = data[i][this.countFieldName];
                if (count) {
                    heatPluginData.push([Math.round(screenpoint.x), Math.round(screenpoint.y), count]);
                } else {
                    heatPluginData.push([Math.round(screenpoint.x), Math.round(screenpoint.y), 1]);
                }
                if (this.minnum > count) {
                    this.minnum = count;
                }
                if (this.maxnum < count) {
                    this.maxnum = count;
                }
            }
            return {
                points: heatPluginData,
                min: this.minnum,
                max: this.maxnum
            };
        },
        //添加点数据
        addPoint: function (data) {
            this.data = data;
            let points = this.convertHeatmapData(data);

            points.points.forEach(point => {
                this.context.beginPath();
                let alpha = (point[2] - points.min) / (points.max - points.min);
                this.context.globalAlpha = alpha;
                this.context.arc(point[0], point[1], this.config.radius, 0, Math.PI * 2, true);
                //绘制一个放射渐变样式的圆
                let gradient = this.context.createRadialGradient(point[0], point[1], 0, point[0], point[1], this.config.radius);
                gradient.addColorStop(0, 'rgba(0,0,0,1)');
                gradient.addColorStop(1, 'rgba(0,0,0,0)');
                this.context.fillStyle = gradient;
                this.context.closePath();
                this.context.fill();
            });
            this.mapColors();
        },
        //设置渐变色带
        getColorPaint: function () {
            let paletteCanvas = document.createElement('canvas');
            let paletteCtx = paletteCanvas.getContext('2d');
            let gradientConfig = this.config.gradient;
            paletteCanvas.width = 256
            paletteCanvas.height = 1
            let gradient = paletteCtx.createLinearGradient(0, 0, 256, 1);
            for (let key in gradientConfig) {
                gradient.addColorStop(key, gradientConfig[key])
            }
            paletteCtx.fillStyle = gradient;
            paletteCtx.fillRect(0, 0, 256, 1);
            return paletteCtx.getImageData(0, 0, 256, 1).data
        },
        //映射颜色
        mapColors: function () {
            let palette = this.getColorPaint();
            let img = this.context.getImageData(0, 0, this.canvas.width, this.canvas.height)
            let imgData = img.data;
            for (let i = 0; i < imgData.length; i++) {
                let alpha = imgData[i];
                let offset = alpha * 4;
                if (!offset) {
                    continue
                }
                //映射颜色RGB值
                imgData[i - 3] = palette[offset];
                imgData[i - 2] = palette[offset + 1];
                imgData[i - 1] = palette[offset + 2];
            }
            this.context.putImageData(img, 0, 0, 0, 0, this.canvas.width, this.canvas.height);
        }
    });
    return HeatMapLayer;
});